﻿using System;
using System.Collections.Generic;
using System.Linq;
using Medianamik.Core;
using Medianamik.Core.Caching;
using Medianamik.Core.Interfaces;
using Medianamik.Core.Querying;

namespace Medianamik.Tests.Integration.Medianamik.UI.Web
{
    public class FakeNodeCacheProvider : CurrentRequestCacheProvider
    {
        private NodeBag _nodeBag;

        protected override NodeBag NodeBag
        {
            get
            {
                if (_nodeBag == null)
                {
                    _nodeBag = new NodeBag();
                }

                return _nodeBag;
            }
        }

        public override IEnumerable<Node> GetNodes(IQueryDefinition pQueryDef)
        {
            if (!pQueryDef.NodeTypeWheres.Any()
                && !pQueryDef.PropertyWheres.Any()
                && pQueryDef.NodeWheres.Any()
                && pQueryDef.NodeWheres[0].MemberInfo.Name == "ID"
                && (pQueryDef.NodeWheres[0].Comparison == Comparison.In
                    || pQueryDef.NodeWheres[0].Comparison == Comparison.Equal))
            {
                var value = pQueryDef.NodeWheres[0].Value;
                if (value is IEnumerable<Guid>)
                {
                    var nodes = NodeBag.Dig((IEnumerable<Guid>)value, (ids) => BuildQuery(ids, false).Execute());
                    foreach (var node in nodes)
                    {
                        yield return node;
                    }
                }
                else
                {
                    if (value is Guid)
                    {
                        var node = NodeBag.Dig((Guid)value, (id) => BuildQuery(id, false).Execute().FirstOrDefault());
                        if (node != null)
                        {
                            yield return node;
                        }
                    }
                }
            }
            else
            {
                var nodes = DALProviderManager.DALProvider.NodeDALProvider.GetNodes(pQueryDef);
                List<Node> addedNodes = new List<Node>();
                List<Node> diggedNodes = new List<Node>();
                foreach (var node in nodes)
                {
                    var diggedNode = NodeBag.Dig(node);
                    diggedNodes.Add(diggedNode);
                    bool added = object.ReferenceEquals(node, diggedNode);
                    if (added)
                    {
                        addedNodes.Add(node);
                    }
                }
                foreach (var node in diggedNodes)
                {
                    yield return node;
                }
            }
        }
    }
}